package com.ygqh.baby.controller;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.ygqh.baby.annotation.WebLog;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.crazycake.shiro.SerializeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.util.JSONPObject;
import com.ygqh.baby.ao.Constant;
import com.ygqh.baby.ao.CustomerStatus;
import com.ygqh.baby.ao.Message;
import com.ygqh.baby.model.CustomerUser;
import com.ygqh.baby.model.YgLoginModel;
import com.ygqh.baby.model.YgUserModel;
import com.ygqh.baby.po.YgUser;
import com.ygqh.baby.redis.RedisDao;
import com.ygqh.baby.service.CustomerUserService;
import com.ygqh.baby.shiro.session.ShiroSessionUtil;

/**
 * @author Ss
 */
@Controller
@RequestMapping("/chat/admin")
public class AdminController extends BaseController {

	@Autowired
	private RedisDao redisDao;
	@Autowired
	private CustomerUserService customerUserService;

	private final static String KEYPREFIX = "shiro_redis_session:";

	@RequestMapping(value = "/unauthorized")
	@ResponseBody
	public JSONPObject unauthorized(String callback) {
		return new JSONPObject(callback, Message.success(new YgLoginModel("REDIRECT_LONGIN_PAGE", Constant.REDIRECT_LONGIN_PAGE)));
	}

	/**
	 * 壹果用户登录
	 *
	 * @param sessionId M站用户登录sessionId
	 * @param callback
	 * @return
	 */
	@WebLog("壹果用户登录")
	@RequestMapping("/ygUserLogin")
	@ResponseBody
	public JSONPObject ygUserLogin(String sessionId, String callback, HttpServletRequest request, HttpServletResponse response) {
		YgLoginModel model = new YgLoginModel("UNKNOWN_ERROR", Constant.UNKNOWN_ERROR);
		YgUser user = findUserInfo(sessionId, request, response);
		if (user != null) {
			String username = user.getUserName();
			String password = user.getPassword();
			model = getLoginModel(username, password);
			if ("LOGIN_SUCCESS".equals(model.getKey())) {
				try {
					customerUserService.updateUserByIsOnline(user.getId(), Boolean.TRUE);
					// 作为用户登录，作为客服退出
					customerUserService.updateCustomerStatus(username, CustomerStatus.Offline);
				} catch (Exception e) {
					logger.error("用户登录失败sessionId----------->" + sessionId);
					e.printStackTrace();
				}
				return new JSONPObject(callback, Message.success(model));
			}
			logger.error("用户登录失败username----------->" + username);
		}
		logger.error("获取redis用户信息失败，sessionId----------->" + sessionId);
		return new JSONPObject(callback, Message.error(model));
	}

	/**
	 * 壹果用户退出
	 *
	 * @param callback callback
	 * @return
	 */
	@WebLog("壹果用户退出")
	@RequestMapping(value = "/ygUserLogout")
	@ResponseBody
	public JSONPObject ygUserLogout(String callback) {
		Subject subject = SecurityUtils.getSubject();
		try {
			YgUserModel user = (YgUserModel) subject.getPrincipal();
			if (user != null) {
				customerUserService.updateUserByIsOnline(user.getId(), Boolean.FALSE);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		subject.logout();
		return new JSONPObject(callback, Message.success(1));
	}

	/**
	 * 客服用户登录
	 *
	 * @param sessionId      sessionId
	 * @param customerStatus customerStatus
	 * @param callback       callback
	 * @param request        request
	 * @param response       response
	 * @return
	 */
	@WebLog("客服用户登录")
	@RequestMapping("/customerUserLogin")
	@ResponseBody
	public JSONPObject customerUserLogin(String sessionId, CustomerStatus customerStatus, String callback,
										 HttpServletRequest request, HttpServletResponse response) {
		YgLoginModel model = new YgLoginModel("UNKNOWN_ERROR", Constant.UNKNOWN_ERROR);
		YgUser user = findUserInfo(sessionId, request, response);
		if (user != null) {
			CustomerUser findByUserId = customerUserService.findByUserName(user.getUserName());
			if (findByUserId == null) {
				return new JSONPObject(callback, Message.error(model));
			}
			String username = user.getUserName();
			String password = user.getPassword();
			model = getLoginModel(username, password);
			if (customerStatus == null || customerStatus.equals(CustomerStatus.Offline)) {
				customerStatus = CustomerStatus.Online;
			}
			customerUserService.updateCustomerStatus(user.getUserName(), customerStatus);
			findByUserId.setCustomerStatus(customerStatus);
			model.setUser(findByUserId);
			logger.debug("session id===============" + sessionId);
			if ("LOGIN_SUCCESS".equals(model.getKey())) {
				return new JSONPObject(callback, Message.success(model));
			}
		}
		return new JSONPObject(callback, Message.error(model));
	}

	private YgUser findUserInfo(String sessionId, ServletRequest request, ServletResponse response) {
		if (StringUtils.isBlank(sessionId)) {
			try {
				sessionId = ShiroSessionUtil.getSessionId(request, response).toString();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		if (StringUtils.isBlank(sessionId)) {
			return null;
		}
		byte[] bs = redisDao.get((KEYPREFIX + sessionId).getBytes());
		if (bs != null) {
			Session session = (Session) SerializeUtils.deserialize(bs);
			SimplePrincipalCollection sCollection = (SimplePrincipalCollection) session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
			Object primaryPrincipal = sCollection.getPrimaryPrincipal();
			if (primaryPrincipal instanceof YgUser) {
				return (YgUser) primaryPrincipal;
			}
		}
		return null;
	}

	/**
	 * 客服用户退出
	 *
	 * @param request
	 * @param request
	 * @param response
	 * @return
	 */
	@WebLog("客服用户退出")
	@RequestMapping(value = "/customerUserLogout")
	@ResponseBody
	public JSONPObject customerUserLogout(String callback, String sessionId, HttpServletRequest request, HttpServletResponse response) {
		Subject subject = SecurityUtils.getSubject();
		try {
			YgUserModel user = (YgUserModel) subject.getPrincipal();
			customerUserService.updateCustomerStatus(user.getUserName(), CustomerStatus.Offline);
			// M站退出
			if (StringUtils.isBlank(sessionId)) {
				try {
					sessionId = ShiroSessionUtil.getSessionId(request, response).toString();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			redisDao.del((KEYPREFIX + sessionId).getBytes());
			subject.logout();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return new JSONPObject(callback, Message.success(1));
	}

	@RequestMapping(value = "/isLogin")
	@ResponseBody
	public JSONPObject isLogin(String callback) {
		return new JSONPObject(callback, Message.success(1));
	}

	private YgLoginModel getLoginModel(String username, String password) {
		Subject subject = SecurityUtils.getSubject();
		UsernamePasswordToken token = new UsernamePasswordToken(username, password);
		YgLoginModel model = new YgLoginModel("LOGIN_SUCCESS", Constant.LOGIN_SUCCESS);
		try {
			subject.login(token);
			model.setUser(subject.getPrincipal());
		} catch (UnknownAccountException e) {
			model = new YgLoginModel("UNKNOWN_ACCOUNT", Constant.UNKNOWN_ACCOUNT);
		} catch (IncorrectCredentialsException e) {
			model = new YgLoginModel("INCORRECTCREDENTIALS", Constant.INCORRECTCREDENTIALS);
		} catch (Exception e) {
			e.printStackTrace();
			model = new YgLoginModel("UNKNOWN_ERROR", Constant.UNKNOWN_ERROR);
		}
		return model;
	}

	/**
	 * 检查 用户名是否是客服
	 *
	 * @return
	 */
	@RequestMapping(value = "/checkKeFuUserName")
	@ResponseBody
	public boolean checkKeFuUserName(@RequestParam String userName) {
		CustomerUser customer = customerUserService.findByUserName(userName);
		return customer != null;

	}

	/**
	 * APP客服登录
	 *
	 * @param sessionId
	 * @param customerStatus
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@WebLog("APP客服登录")
	@RequestMapping("/appCustomerUserLogin")
	@ResponseBody
	public Map<String, String> appCustomerUserLogin(String sessionId, CustomerStatus customerStatus, String appType,
													HttpServletRequest request, HttpServletResponse response) {
		YgLoginModel model;
		YgUser user = findUserInfo(sessionId, request, response);
		Map<String, String> map = new HashMap<>();
		map.put("isCustomer", "0");
		if (user != null) {
			CustomerUser findByUserId = customerUserService.findByUserName(user.getUserName());
			if (findByUserId == null) {
				map.put("isCustomer", "0");
				return map;
			}
			String username = user.getUserName();
			String password = user.getPassword();
			model = getLoginModel(username, password);
			if (customerStatus == null || customerStatus.equals(CustomerStatus.Offline)) {
				customerStatus = CustomerStatus.Online;
			}
			customerUserService.updateCustomerStatus(user.getUserName(), customerStatus);
			findByUserId.setCustomerStatus(customerStatus);
			model.setUser(findByUserId);
			//借用字段
			findByUserId.setUpdateBy(sessionId);
			findByUserId.setCreateBy(appType);

			redisDao.set("APP_" + findByUserId.getId(), JSON.toJSONString(findByUserId), 0);
			logger.debug("session id===============" + sessionId);
			if ("LOGIN_SUCCESS".equals(model.getKey())) {
				map.put("isCustomer", "1");
			}
		}
		return map;
	}

	/**
	 * APP客服用户退出
	 *
	 * @param request
	 * @param request
	 * @param response
	 * @return
	 */
	@WebLog("APP客服退出")
	@RequestMapping(value = "/appCustomerUserLogout")
	@ResponseBody
	public Map<String, String> appCustomerUserLogout(String sessionId, HttpServletRequest request, HttpServletResponse response) {
		Subject subject = SecurityUtils.getSubject();
		Map<String, String> map = new HashMap<>();
		map.put("exist", "ok");
		try {
			YgUserModel user = (YgUserModel) subject.getPrincipal();
			customerUserService.updateCustomerWithLogout(user.getUserName());
			// M站退出
			if (StringUtils.isBlank(sessionId)) {
				try {
					sessionId = ShiroSessionUtil.getSessionId(request, response).toString();
				} catch (Exception e) {
					e.printStackTrace();
					map.put("exist", "error");
				}
			}
			System.out.println(sessionId);
			redisDao.del((KEYPREFIX + sessionId).getBytes());
			redisDao.del(("APP_" + user.getId()).getBytes());
			subject.logout();
		} catch (Exception e) {
			e.printStackTrace();
			map.put("exist", "error");
		}

		return map;
	}
}
